/**
 * Framework for batch testing user profile models
 * Final project by Sergey Nepomnyachiy and Julia Polchin
 * Supervisor: Tsvi Kuflik
 *
 */
package core.generators;

import interfaces.GeneratorInterface;

import java.util.Collection;
import java.util.Vector;

/**
 * Generic generator that uses generating "function" to produce values vector.
 * Note: many other more specific generators are implemented with this one.
 * 
 * @author Sergey&Julia
 * 
 * @param <T>
 *            The data type of choice
 */
public abstract class FunctionGenerator<T> implements GeneratorInterface<T> {
	protected Vector<T> vector;
	protected T start;

	/**
	 * This function should be overridden with generating function
	 * 
	 * @param index
	 *            For some generating functions the position matters, other may
	 *            just ignore it
	 * @return the generated value of generic type T
	 */
	abstract T function(int index);

	/**
	 * Constructor for function generator
	 * 
	 * @param start
	 *            The starting value of generic type T
	 * @param count
	 *            How many values shall the generator produce
	 */
	@SuppressWarnings("unchecked")
	FunctionGenerator(Object start) {
		this.vector = new Vector<T>();
		this.start = (T) start;
	}

	/**
	 * Generates the desired vector
	 * 
	 * @param count
	 *            Just how many elements to create
	 * @return self reference this in all cases
	 */
	public GeneratorInterface<T> generate(int count) {
		for (int i = 0; i < count; ++i)
			this.vector.add(function(i));
		return this;
	}

	/**
	 * Getter for the generated vector
	 * 
	 * @return Collection of generic type T
	 */
	public Collection<T> getVector() {
		return this.vector;
	}

	/**
	 * Getter for generated scalar
	 * 
	 * @return Generated scalar of type T
	 */
	public T getScalar() {
		return function(0); // default behavior
	}

	/**
	 * Used to easily check if generator returned 1D or 2D structure
	 * 
	 * @return true if generator creates a matrix, false if it is a set or
	 *         vector
	 */
	public boolean is2D() {
		return false;
	}
}
